﻿using ERPWinFormWork.Common;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ERPWinFormWork.Material
{
    public class ApiClient
    {
        private readonly HttpClient _httpClient;
        private readonly string _baseUrl;
        private string _token; // Token存储属性

        // 初始化，传入API基础地址
        public ApiClient(string baseUrl)
        {
            _baseUrl = baseUrl;
            _httpClient = new HttpClient();
            _httpClient.BaseAddress = new Uri(baseUrl);
            // 设置超时时间
            _httpClient.Timeout = TimeSpan.FromSeconds(30);
            // 尝试自动从TokenManager获取Token
            TrySetTokenFromManager();
        }

        // 尝试从TokenManager设置Token
        private void TrySetTokenFromManager()
        {
            if (!string.IsNullOrEmpty(TokenManager.JwtToken))
            {
                _token = TokenManager.JwtToken;
            }
        }



        // 自动从TokenManager更新Token的方法
        public void UpdateTokenFromManager()
        {
            TrySetTokenFromManager();
        }

        // GET请求（泛型方法，自动反序列化JSON）
        public async Task<T> GetAsync<T>(string endpoint, Dictionary<string, string> parameters = null)
        {
            try
            {
                var requestUrl = endpoint;
                if (parameters != null && parameters.Count > 0)
                {
                    requestUrl += "?" + string.Join("&", parameters.Select(kv => $"{kv.Key}={kv.Value}"));
                }

                // 创建请求消息
                var request = new HttpRequestMessage(HttpMethod.Get, requestUrl);
                // 添加Token到请求头
                if (!string.IsNullOrEmpty(_token))
                {
                    request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", _token);
                }

                // 2. 打印最终请求 URL（调试用，确认参数已拼接）
                var fullUrl = _httpClient.BaseAddress + requestUrl;
                // 3. 发送带参数的 GET 请求
                var response = await _httpClient.SendAsync(request);
                response.EnsureSuccessStatusCode(); // 若 API 报错（如 404），会抛出提示

                // 4. 解析 JSON 数据
                var json = await response.Content.ReadAsStringAsync();
                Console.WriteLine($"API 返回数据：{json}"); // 调试用，确认返回内容
                return JsonConvert.DeserializeObject<T>(json);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"GET请求失败：{ex.Message}");
                return default;
            }
        }

        // POST请求（泛型方法，自动序列化JSON）
        public async Task<TResult> PostAsync<TData, TResult>(string endpoint, TData data)
        {
            try
            {
               

                var json = JsonConvert.SerializeObject(data);
                var content = new StringContent(json, Encoding.UTF8, "application/json");

                // 打印请求信息（调试用）
                var fullUrl = _httpClient.BaseAddress + endpoint;
                Console.WriteLine($"POST请求URL：{fullUrl}");
                Console.WriteLine($"POST请求数据：{json}");

                // 创建请求消息
                var request = new HttpRequestMessage(HttpMethod.Post, endpoint);
                request.Content = content;
                // 添加Token到请求头
                if (!string.IsNullOrEmpty(_token))
                {
                    request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", _token);
                }


                var response = await _httpClient.SendAsync(request);
                
                // 读取响应内容
                var responseJson = await response.Content.ReadAsStringAsync();
                Console.WriteLine($"POST响应状态码：{response.StatusCode}");
                Console.WriteLine($"POST响应内容：{responseJson}");

                // 检查HTTP状态码
                if (!response.IsSuccessStatusCode)
                {
                    var errorMessage = $"HTTP错误 {response.StatusCode}: {responseJson}";
                    Console.WriteLine($"POST请求HTTP错误：{errorMessage}");
                    MessageBox.Show(errorMessage, "HTTP错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return default;
                }

                return JsonConvert.DeserializeObject<TResult>(responseJson);
            }
            catch (HttpRequestException httpEx)
            {
                Console.WriteLine($"POST请求网络异常：{httpEx.Message}");
                MessageBox.Show($"网络请求失败：{httpEx.Message}", "网络错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return default;
            }
            catch (JsonException jsonEx)
            {
                Console.WriteLine($"POST请求JSON序列化异常：{jsonEx.Message}");
                MessageBox.Show($"数据格式错误：{jsonEx.Message}", "格式错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return default;
            }
            catch (TaskCanceledException taskEx)
            {
                Console.WriteLine($"POST请求超时异常：{taskEx.Message}");
                MessageBox.Show($"请求超时：{taskEx.Message}", "超时错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return default;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"POST请求其他异常：{ex.Message}");
                Console.WriteLine($"POST请求异常堆栈：{ex.StackTrace}");
                MessageBox.Show($"POST请求失败：{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return default;
            }
        }

        // DELETE请求（带参数）
        public async Task<T> DeleteAsync<T>(string endpoint, Dictionary<string, string> parameters = null)
        {
            try
            {
                var requestUrl = endpoint;
                if (parameters != null && parameters.Count > 0)
                {
                    requestUrl += "?" + string.Join("&", parameters.Select(kv => $"{kv.Key}={Uri.EscapeDataString(kv.Value)}"));
                }

                // 创建请求消息
                var request = new HttpRequestMessage(HttpMethod.Delete, requestUrl);
                // 添加Token到请求头
                if (!string.IsNullOrEmpty(_token))
                {
                    request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", _token);
                }

                var response = await _httpClient.SendAsync(request);
                response.EnsureSuccessStatusCode();

                var json = await response.Content.ReadAsStringAsync();
                Console.WriteLine($"DELETE API 返回数据：{json}");
                return JsonConvert.DeserializeObject<T>(json);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"DELETE请求失败：{ex.Message}");
                return default;
            }
        }

      

        // PUT请求（发送JSON数据，同时将简单属性拼到Query以兼容后端FromQuery）
        public async Task<TResult> PutAsync<TData, TResult>(string endpoint, TData data)
        {
            try
            {
                var requestUrl = endpoint;
                // 使用 Newtonsoft.Json 序列化数据为JSON
                var json = JsonConvert.SerializeObject(data);
                var content = new StringContent(json, Encoding.UTF8, "application/json");

                // 将对象的简单属性附加为查询参数（兼容后端 Swagger 显示的 query 绑定）
                if (data != null)
                {
                    var props = typeof(TData).GetProperties();
                    var queryPairs = new List<string>();
                    foreach (var p in props)
                    {
                        var value = p.GetValue(data, null);
                        if (value == null) continue;
                        // 仅处理原始可序列化为字符串的简单类型
                        var str = Convert.ToString(value);
                        if (str == null) continue;
                        queryPairs.Add($"{Uri.EscapeDataString(p.Name)}={Uri.EscapeDataString(str)}");
                    }
                    if (queryPairs.Count > 0)
                    {
                        requestUrl += (requestUrl.Contains("?") ? "&" : "?") + string.Join("&", queryPairs);
                    }
                }

                // 打印请求信息（调试用）
                var fullUrl = _httpClient.BaseAddress + endpoint;
                Console.WriteLine($"PUT请求URL：{fullUrl}");
                Console.WriteLine($"PUT请求数据：{json}");
                // 创建请求消息
                var request = new HttpRequestMessage(HttpMethod.Put, requestUrl);
                request.Content = content; // 发送JSON请求体
                // 添加Token到请求头
                if (!string.IsNullOrEmpty(_token))
                {
                    request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", _token);
                }

                var response = await _httpClient.SendAsync(request);
                
                // 打印响应状态码
                Console.WriteLine($"PUT响应状态码：{response.StatusCode}");
                
                // 读取响应内容
                var resultJson = await response.Content.ReadAsStringAsync();
                Console.WriteLine($"PUT响应内容：{resultJson}");
                
                // 检查响应状态码
                if (!response.IsSuccessStatusCode)
                {
                    Console.WriteLine($"PUT请求失败，状态码：{response.StatusCode}，响应内容：{resultJson}");
                    MessageBox.Show($"PUT请求失败，状态码：{response.StatusCode}，响应内容：{resultJson}");
                    return default;
                }


                // 使用 Newtonsoft.Json 反序列化结果
                var result = JsonConvert.DeserializeObject<TResult>(resultJson);
                Console.WriteLine($"PUT反序列化结果：{JsonConvert.SerializeObject(result)}");
                return result;

            }
            catch (HttpRequestException httpEx)
            {
                Console.WriteLine($"PUT请求HTTP异常：{httpEx.Message}");
                if (httpEx.InnerException != null)
                {
                    Console.WriteLine($"PUT请求内部异常：{httpEx.InnerException.Message}");
                }
                MessageBox.Show($"PUT请求HTTP异常：{httpEx.Message}");
                return default;
            }
            catch (TaskCanceledException taskEx)
            {
                Console.WriteLine($"PUT请求超时异常：{taskEx.Message}");
                MessageBox.Show($"PUT请求超时异常：{taskEx.Message}");
                return default;
            }
            catch (JsonException jsonEx)
            {
                Console.WriteLine($"PUT请求JSON序列化异常：{jsonEx.Message}");
                MessageBox.Show($"PUT请求JSON序列化异常：{jsonEx.Message}");
                return default;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"PUT请求其他异常：{ex.Message}");
                Console.WriteLine($"PUT请求异常堆栈：{ex.StackTrace}");
                MessageBox.Show($"PUT请求失败：{ex.Message}");
                return default;
            }
        }


        public async Task<byte[]> GetBytesAsync(string endpoint, Dictionary<string, string> parameters = null)
        {
            try
            {
                var requestUrl = endpoint;
                if (parameters != null && parameters.Count > 0)
                {
                    // 处理参数转义（中文、空格等）
                    requestUrl += "?" + string.Join("&",
                        parameters.Select(kv => $"{Uri.EscapeDataString(kv.Key)}={Uri.EscapeDataString(kv.Value ?? string.Empty)}")
                    );
                }

                // 调试用：打印Excel下载请求URL
                var fullUrl = _httpClient.BaseAddress + requestUrl;
                Console.WriteLine($"Excel下载请求URL：{fullUrl}");

                // 创建GET请求消息
                var request = new HttpRequestMessage(HttpMethod.Get, requestUrl);

                // 添加Token认证头
                if (!string.IsNullOrEmpty(_token))
                {
                    request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", _token);
                }

                // 发送GET请求，获取Excel流
                var response = await _httpClient.SendAsync(request);
                response.EnsureSuccessStatusCode(); // 后端返回400（无数据）、500（错误）会抛出异常

                // 读取二进制流（Excel文件的字节数组）
                byte[] fileBytes = await response.Content.ReadAsByteArrayAsync();
                Console.WriteLine($"获取到Excel字节数：{fileBytes.Length} 字节");
                return fileBytes;
            }
            catch (Exception ex)
            {
                // 捕获后端返回的错误信息（如“无导出数据”）
                string errorMsg = ex.Message;
                // 若为HttpRequestException，尝试读取后端返回的错误内容
                if (ex is HttpRequestException httpEx && httpEx.InnerException != null)
                {
                    errorMsg += $"\n后端提示：{httpEx.InnerException.Message}";
                }
                MessageBox.Show($"Excel下载请求失败：{errorMsg}");
                return null; // 失败时返回null，前端可判断
            }
        }




        /// <summary>
        /// 上传文件（multipart/form-data格式）
        /// </summary>
        /// <param name="endpoint">接口地址（如"File/UploadFile"）</param>
        /// <param name="filePath">本地文件路径</param>
        /// <param name="formFieldName">接口接收文件的参数名（通常是"file"）</param>
        public async Task<string> UploadFileAsync<TResult>(string endpoint, string filePath, string formFieldName = "file")
        {
            try
            {
                // 检查文件是否存在
                if (!File.Exists(filePath))
                {
                    MessageBox.Show("文件不存在：" + filePath);
                    return default;
                }

                // 创建 multipart/form-data 内容
                using (var formData = new MultipartFormDataContent())
                {
                    // 读取文件流并添加到请求
                    using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
                    {
                        var fileContent = new StreamContent(fileStream);
                        // 设置文件内容类型（根据实际文件类型调整，这里用通用二进制）
                        fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/octet-stream");

                        // 添加文件到表单（参数名需与接口一致）
                        formData.Add(
                            content: fileContent,
                            name: formFieldName,
                            fileName: Path.GetFileName(filePath) // 传给接口的文件名
                        );

                        // 创建请求消息
                        var request = new HttpRequestMessage(HttpMethod.Post, endpoint);
                        request.Content = formData;

                        // 添加Token（复用原有逻辑）
                        if (!string.IsNullOrEmpty(_token))
                        {
                            request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _token);
                        }

                        // 发送请求
                        var response = await _httpClient.SendAsync(request);
                        response.EnsureSuccessStatusCode();


                        string minioImageUrl = await response.Content.ReadAsStringAsync();
                        return minioImageUrl;
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"文件上传失败：{ex.Message}");
                return default;
            }
        }
    }
}
